package com.km.team.phsystem.msg.service;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.km.team.phsystem.beans.pojo.IdentifySms;
import com.km.team.phsystem.beans.pojo.IdentifySmsExample;
import com.km.team.phsystem.beans.pojo.NoticeSms;
import com.km.team.phsystem.common.enums.ReservationTypeEnum;
import com.km.team.phsystem.dao.mybatis.IdentifySmsMapper;
import com.km.team.phsystem.dao.mybatis.NoticeSmsMapper;
import com.km.team.phsystem.dao.mybatis.custom.IdentifySmsMapperCustom;
import com.km.team.phsystem.msg.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("smsService")
@Component
public class SmsServiceImpl implements ISmsService {

    @Autowired
    private IdentifySmsMapper identifySmsMapper;

    @Autowired
    private IdentifySmsMapperCustom identifySmsCustom;

    @Autowired
    private NoticeSmsMapper noticeSmsMapper;

    @Autowired
    private SmsProps smsProps;


    /**
     * 发送短信, 并插表
     *
     * @param
     * @return
     */
    @Override
    public String sendNoticeSms(String phoneNo, String dateTimeStr, String number, String businessType, ReservationTypeEnum type) {
        if (businessType.length() > 20) {
            businessType = businessType.substring(0, 17) + "...";
        }
        Map<String, String> map = new HashMap<>();
        map.put("time", "\"" + dateTimeStr + "\"");
        map.put("businessType", "\"" + businessType + "\"");
        map.put("number", "\"" + number + "\"");
        SendSmsResponse response = null;
        try {
            if(ReservationTypeEnum.RESERVATION_TYPE_FIXED_APPOINTMENT.getType().equals(type)){
                response = sendSms(phoneNo, "SMS_155862726", map);
            }else{
                response = sendSms(phoneNo, "SMS_155862729", map);
            }
            if (response.getCode().equalsIgnoreCase("OK")) {
                NoticeSms sms = new NoticeSms();
                sms.setContent(smsProps.getTemplates().get("notice").replaceAll("\\{time\\}", dateTimeStr).replaceAll("\\{number\\}", number).replaceAll("\\{businessType\\}", businessType));
                sms.setSendTime(new Date());
                sms.setPhoneNo(phoneNo);
                noticeSmsMapper.insert(sms);
                return "success";
            } else {
                throw new RuntimeException("发送短信失败：" + response.getMessage());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("发送短信失败：" + (response != null ? response.getMessage() : null));
        }

    }

    /**
     * 发送验证码(用户获取短信验证码)
     *
     * @param phoneNo 电话号码
     * @return 发送提示信息
     */
    @Override
    public IdentifyResponse sendIdentifySms(final String phoneNo) throws Exception {
        //一分钟内不能重复获取验证码
        final IdentifySms latestSms = identifySmsCustom.getLatestIdentifySms(phoneNo);
        final Date now = new Date();
        final IdentifyResponse identifyResponse = new IdentifyResponse();
        if (latestSms == null || now.after(latestSms.getExpireTime())) {
            final String code = IdGenerator.genId(6);
            final Map<String, String> params = new HashMap<>();
            params.put("code", "\"" + code + "\"");
            SendSmsResponse response = sendSms(phoneNo, "SMS_149101229", params);
            if (response.getCode().equalsIgnoreCase("OK")) {
                identifyResponse.setCode(code);

                IdentifySms sms = new IdentifySms();
                sms.setSendTime(now);
                sms.setPhoneNo(phoneNo);
                sms.setCode(code);
                sms.setStatus(true);
                sms.setSendTime(now);
                sms.setExpireTime(new Date(now.getTime() + 60 * 1000));
                sms.setContent(smsProps.getTemplates().get("identify").replaceAll("\\{\\}", code));
                identifySmsMapper.insert(sms);

                identifyResponse.setMessage("获取验证码成功");
            } else {
                identifyResponse.setMessage("获取验证码失败，请稍后再试");
            }
        } else {
            identifyResponse.setMessage("不能频繁操作获取验证码，获取间隔1分钟");
        }
        return identifyResponse;
    }


    /**
     * 发送短信
     *
     * @param phoneNo 电话号码
     * @param tplCode 模板编码
     * @param params  参数
     * @return 发送短信Response消息
     * @throws Exception 1
     */
    private SendSmsResponse sendSms(final String phoneNo, final String tplCode, final Map<String, String> params) throws Exception {
        final SmsDto sms = new SmsDto();
        sms.setPhoneNo(phoneNo);
        sms.setTplParam(params);
        sms.setSignName("高新人社");
        sms.setTplCode(tplCode);
        return SMSender.sendSms(sms);
    }


    /**
     * 验证验证码是否有效
     *
     * @param phoneNo 电话号码
     * @param code    验证码
     * @return 有效则返回“success”,否则返回“failure”
     */
    @Override
    public String verifyIdentifyCode(final String phoneNo, final String code) throws Exception {
        final IdentifySmsExample example = new IdentifySmsExample();
        example.createCriteria()
            .andCodeEqualTo(code)
            .andPhoneNoEqualTo(phoneNo)
            .andExpireTimeGreaterThan(new Date())
            .andStatusEqualTo(true);
        final List<IdentifySms> identifySmsList = identifySmsMapper.selectByExample(example);
        return identifySmsList.size() > 0 ? "success" : "failure";
    }


    /**
     * 用于用户登录或拍号成功后，将验证码设置为无效
     *
     * @param phoneNo 电话号码
     * @param code    验证码
     * @return 是否更新或失败
     */
    @Override
    public void disableIdentifyStatus(final String phoneNo, final String code) throws Exception {
        final IdentifySms identifySms = new IdentifySms();
        identifySms.setStatus(false);
        final IdentifySmsExample example = new IdentifySmsExample();
        example.createCriteria().andCodeEqualTo(code).andPhoneNoEqualTo(phoneNo);
        identifySmsMapper.updateByExampleSelective(identifySms, example);

    }

}
